#pragma once


namespace chain
{
	template<class T>
	struct list_node
	{
		list_node() = default;

		list_node(T& x)
		{
			_data = x;
		}

		T _data;
		T* _prev = nullptr;
		T* _next = nullptr;
	};

	template<class T>
	struct list_iterator
	{
		typedef list_iterator<T> iterator;
		typedef list_node<T> Node;

		list_iterator(Node* tmp)
			:_node(tmp)
		{

		}

		T& operator * ()
		{
			return _node->_data;
		}

		iterator operator ++ ()
		{
			return _node->_next;
		}

		iterator operator ++ (int)
		{
			Node* tmp = _node;
			_node = _node->_next;
			return tmp;
		}

		iterator operator -- ()
		{
			return _node->_prev;
		}

		iterator operator -- (int)
		{
			Node* tmp = _node;
			_node = _node->_prev;
			return tmp;
		}

		Node* _node;
	};

	template<class T>
	class list
	{
		typedef list_node<T> Node ;
		typedef list_iterator<T> iterator ;
	public:
		list()
		{
			_head = new Node (T());
			_head->_next = _head;
			_head->_prev = _head;
		}

		void push_back(const T& x)
		{
			Node* tmp = new Node (x);
			//tmp->_data = x;
			Node* tail = _head->_prev;

			tail->_next = tmp;
			tmp->_prev = tail;
			_head->_prev = tmp;
			tmp->_next = _head;
			++_size;
		}

	private:
		Node* _head = nullptr;
		size_t _size = 0;
		//T* node = nullptr;
	};
}